#ifndef APZP1Algorithm_H
#define APZP1Algorithm_H

#include "AdaptiveAlgorithmBase.h"

// Identyfikator janka
#include "SimEngine/RmnkSolver.h"

// Klasa wielomianu
#include "SimEngine/Polynomial.h"

namespace RafMat
{
namespace SimEngine
{

class APZP1Algorithm : public AdaptiveAlgorithmBase
{
public:
    static const double DEFAULT_LAMBDA;

    APZP1Algorithm(RSTController& owner, int k = 1, int ndR = 1, int ndS = 1 );

    bool setParameter(const std::string& param, const std::string& value) throw(std::logic_error);

    std::string getParameter(const std::string& param) const throw(std::logic_error);

    void adapt(double ctrlVar, double processVar, double setPoint);

    void reset();

    virtual SimFile::ConfigWriter& dumpParameters(SimFile::ConfigWriter& o) const;

private:
    static const std::string CONF_AMPOLY;
    static const std::string CONF_BMPOLY;
//    static const std::string CONF_BPLUS;
    static const std::string CONF_RDEGREE;
    static const std::string CONF_SDEGREE;
    static const std::string CONF_KDELAY;

    void resetWrnmnk();
    void resizeBuffers();
    void cleanBuffers();

    void setAMPoly(const Polynomial& amPoly);
    void setBMPoly(const Polynomial& bmPoly);
//    void setBPlusPoly(const Polynomial& bpPoly);
    void setRDegree(unsigned int ndR);
    void setSDegree(unsigned int ndS);
    void setKDelay(unsigned int k);

    std::deque<double> m_ymem;      ///< Pamięć próbek y
    std::deque<double> m_umem;      ///< Pamięć próbek u

    Polynomial m_AmPoly;
    Polynomial m_BmPoly;
//    Polynomial m_BPlusPoly;

    unsigned m_k;                        ///< Opóźnienie
    unsigned m_ndR;
    unsigned m_ndS;

    RmnkSolverSPtr m_wrmnk;        ///< Obiekt do identyfikacji modelu
    RmnkSolver::Matrix m_theta;
    RmnkSolver::Matrix m_phi;
};


}
}

#endif // APZP1Algorithm_H
